#include "stdafx.h"
#include "hqServer.h"
#include "util_win.h"
#include "WZSocket.h"

char csBuf[websock_buf_size];	// data need  be sent in CS
int csBufLen = 0;
SockList* pHeadSock = NULL;
SockList* pLast = NULL;

DWORD WINAPI sendDataThread(LPVOID pParam)
{
	while (TRUE)
	{
		EnterCriticalSection(&g_queueCS);
		SockList* pCur = pHeadSock;
		while (pCur != NULL && csBufLen > 0)
		{
			send(pCur->pSockContent->m_Socket, csBuf, csBufLen, 0);
			//zclog(CL_LITE_YELLOW, "[ %d ] sent %d....\n", GetCurrentThreadId(), pCur->sid);
			pCur = pCur->next;
		}
		csBufLen = 0;
		LeaveCriticalSection(&g_queueCS);
		Sleep(10);
	}

	return 0;
}
hqServer::hqServer()
{
	InitializeCriticalSection(&g_queueCS);
	ZeroMemory(csBuf, websock_buf_size);
	index_no = 0;
}
hqServer::~hqServer()
{
}

void hqServer::appendData(char* pData, int len)
{
	EnterCriticalSection(&g_queueCS);
	//zclog(CL_LITE_YELLOW, "[ %d ] writing.... %d\n", GetCurrentThreadId(), len);
	memcpy(csBuf, pData, len);
	csBufLen = len;
	LeaveCriticalSection(&g_queueCS);
}
void hqServer::onConnect(PerSockContext* pSockContext, sockaddr_in* client) {
	char* clientIP = inet_ntoa(client->sin_addr);
	int clientPort = client->sin_port;

	zclog(CL_YELLOW, "%d %s:%d___________connected\n", pSockContext->m_Socket, clientIP, clientPort);
	/*pSockContext->wsaRecvBuf = new char[RECV_BUF_SIZE];
	pSockContext->wsaSendBuf = new char[SEND_BUF_SIZE];*/
	pSockContext->m_SendbufSize = SEND_BUF_SIZE;
	pSockContext->m_RecvbufSize = RECV_BUF_SIZE;

}
void hqServer::onConnectRefused(PerSockContext* pSockContext) {
	zclog(CL_YELLOW, "[Remote %d ] connect REFUSED\n", pSockContext->m_Socket);
}
void hqServer::onConnectBroken(PerSockContext* pSockContext) {
	zclog(CL_YELLOW, "[Remote %d ] connection broken \n", pSockContext->m_Socket);
}
int hqServer::onRecv(PerSockContext* pSockContext, DWORD recvdBytes){
	// see if there has had a connection in context
	SockList* p = pHeadSock;
	while (p != NULL) {
		if (p->pSockContent == pSockContext) {
			return 0; // exist , do nothing, DONT close !
		}
		p = p->next;
	}

	// check if buf is less than 12, not enough login, close and wait reconnect
	//if (recvdBytes < 12) { return -1; }

	// check username and password
	index_no++;
	//if (strstr(pSockContext->wsaRecvBuf, "m=HI;u=aaa;p=bbb") != NULL){
	SockList* newSock = new SockList;
	newSock->pSockContent = pSockContext;
	newSock->sid = index_no;
	EnterCriticalSection(&g_queueCS);
	// add to list
	if (pHeadSock == NULL){
		pHeadSock = newSock;
		pLast = newSock;
	}
	else{
		pLast->next = newSock;
		pLast = newSock;
	}

	LeaveCriticalSection(&g_queueCS);
	//} else return -1;
	return 0;
}

int hqServer::onDisconnect(PerSockContext* pSockContext) {
	EnterCriticalSection(&g_queueCS);
	// remove from list
	zclog(CL_YELLOW, "[Client %d ] disconnected. \n", pSockContext->m_Socket);

	SockList* pCur = pHeadSock;
	SockList* pCurLast = pHeadSock;
	while (pCur != NULL)
	{
		if (pCur->pSockContent->m_Socket == pSockContext->m_Socket){
			if (pCur == pHeadSock){
				delete pCur;
				pHeadSock = NULL;
			}
			else{
				pCurLast->next = pCur->next;
				delete pCur;
			}
			
			break;
		}
		pCurLast = pCur;
		pCur = pCur->next;
	}

	LeaveCriticalSection(&g_queueCS);

	return 0;
}

void hqServer::onExceptionClose(PerSockContext* pSockContext) {
	zclog(CL_YELLOW, "exception close sock %d\n", pSockContext->m_Socket);
	EnterCriticalSection(&g_queueCS);
	// remove from list
	SockList* pCur = pHeadSock;
	SockList* pCurLast = pHeadSock;
	while (pCur != NULL)
	{
		if (pCur->pSockContent->m_Socket == pSockContext->m_Socket){
			if (pCur == pHeadSock){
				delete pCur;
				pHeadSock = NULL;
			}
			else{
				pCurLast->next = pCur->next;
				delete pCur;
			}

			break;
		}
		pCurLast = pCur;
		pCur = pCur->next;
	}

	LeaveCriticalSection(&g_queueCS);
}